package com.jrx.anytxn.customer.handel.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnArgumentException;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.bean.CustomerInfoCreationBean;
import com.jrx.anytxn.customer.bean.MarketingRecordCreationBean;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.constant.ErrorMsgConstant;
import com.jrx.anytxn.customer.dto.customer.AddressInfoReq;
import com.jrx.anytxn.customer.dto.customer.ContactInfoReq;
import com.jrx.anytxn.customer.dto.customer.CustSecondLevelModReq;
import com.jrx.anytxn.customer.dto.customer.CustomeMobileModifyReq;
import com.jrx.anytxn.customer.dto.customer.CustomeRegisterMarketingRecordReq;
import com.jrx.anytxn.customer.dto.customer.CustomerEcifReq;
import com.jrx.anytxn.customer.dto.customer.CustomerRegisterReq;
import com.jrx.anytxn.customer.dto.customer.CustomerReq;
import com.jrx.anytxn.customer.dto.customer.CustomerSupplyReq;
import com.jrx.anytxn.customer.dto.customer.IdValidityReq;
import com.jrx.anytxn.customer.entity.CmCustomerAddressInfo;
import com.jrx.anytxn.customer.entity.CmCustomerContactInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.entity.CmCustomerLabel;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.TlMarketingRecord;
import com.jrx.anytxn.customer.enums.CustomerMaintenanceType;
import com.jrx.anytxn.customer.handel.ICustomerHander;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerAddressInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerContactInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtTlMarketingRecordMapper;
import com.jrx.anytxn.customer.plugins.HistoryLog;
import com.jrx.anytxn.customer.plugins.HistoryLogHelper;
import com.jrx.anytxn.customer.service.ICustomerLabelService;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrChannelTable;
import com.jrx.anytxn.param.entity.TlCustomerLabelLog;
import com.jrx.anytxn.param.service.rights.ITlCustomerLabelLogService;
import com.jrx.anytxn.param.service.system.IChannelTableService;
import com.jrx.anytxn.redisson.service.RedissonLockService;
import com.jrx.anytxn.redisson.util.LockType;
import com.jrx.anytxn.sharding.pojo.entity.CacheMapping;
import com.jrx.anytxn.sharding.service.ICacheMappingService;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author qingyao.xing
 * @version 1.0
 * @date 2019/10/22
 */
@Component
public class CustomerHanderImpl implements ICustomerHander {


    private static final Logger logger = LoggerFactory.getLogger(CustomerHanderImpl.class);
    @Autowired
    private IChannelTableService channelTableService;
    @Autowired
    private ICustomerService customerService;
    @Autowired(required = false)
    private ICacheMappingService cacheMappingService;
    @Autowired
    private ISegmentService iSegmentService;
    @Autowired
    private RedissonLockService redissonLockService;
    @Resource
    private ExtTlMarketingRecordMapper extTlMarketingRecordMapper;
    @Autowired
    ITlCustomerLabelLogService tlCustomerLabelLogService;
    @Autowired
    ICustomerLabelService customerLabelService;

    @Resource
    private ExtCmCustomerSecondLevelMapper extCmCustomerSecondLevelMapper;

    @Resource
    private ExtCmCustomerAddressInfoMapper extCmCustomerAddressInfoMapper;
    @Resource
    private ExtCmCustomerContactInfoMapper extCmCustomerContactInfoMapper;

    /**
     * 客户建档
     *
     * @param req 建档请求
     */
    @Override
    public void customerInfoCreation(CustomerReq req) throws Exception {
        String lockKey = String.format(CustomerConstant.LOCK_CUST, req.getTenantId(), req.getUserId(),
                req.getChannel());
        logger.info("RedissionLock key:{}", lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.REDIS_LOCK_WAITE_TIME,
                    CustomerConstant.REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}", lockKey, lockFlag);
            if (!lockFlag) {
                logger.error(ErrorMsgConstant.LOCK_EXIST);
                throw new TxnBizException(TxnRespCode.TRANSACTION_PROCESSING.getCode(), TxnRespCode.TRANSACTION_PROCESSING.getMsg());
            }

            //验证证件 起始日期大于终止日期
            this.verifyIdNumberDate(req.getIdEffectiveDate(), req.getIdExpireDate());
            //请求报文校验
            PrChannelTable channelTable = channelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, req.getChannel(), req.getTenantId());
            String privateChannel = channelTable.getPrivateChannel();

            String customerType;
            if (StringUtils.isEmpty(privateChannel) || privateChannel.equals(CustomerConstant.PRIVATE_CHANNEL_YES)) {
                //自营客户
                customerType = CustomerConstant.CUSTOMER_TYPE_SELF;
            } else {
                //非自营客户
                customerType = CustomerConstant.CUSTOMER_TYPE_PARTNERSHIP;
            }
            //根据证件号和tenanId查询分路由
            CacheMapping cacheMapping = cacheMappingService.selectFromCacheByIdNumber(req.getTenantId(), req.getIdNumber(), true);
            logger.info("根据证件号[{}]租户[{}]获取路由信息[{}]", req.getIdNumber(), req.getTenantId(), cacheMapping);
            if (null == cacheMapping) {
                //证件路由不存在 校验路由信息
                this.check(req.getUserId(), req.getChannel(), req.getMobile(), req.getTenantId());
                //获取操作 bean
                CustomerInfoCreationBean customerOperationBean = this.getCustomerOperationBean(req, null, null, channelTable, customerType);
                customerService.saveInfo(customerOperationBean);
                return;
            }
            //路由中存在缓存
            //根据机构+证件类型+证件号查询客户一级信息记录
            CmCustomerFirstLevel firstlevel = customerService.getFirstLevelByCondition(cacheMapping.getCustomerId(), channelTable.getOrganizationId(), req.getTenantId(), req.getIdType(), req.getIdNumber());
            logger.info("根据客户id[{}]证件号[{}租户[{}]机构号[{}]获取客户一级表信息[{}]", cacheMapping.getCustomerId(), req.getIdNumber(), req.getTenantId(), channelTable.getOrganizationId(), firstlevel);
            if (null == firstlevel) {
                //证件路由存在，一级表不存在 校验路由信息
                this.check(req.getUserId(), req.getChannel(), req.getMobile(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerOperationBean(req, null, null, channelTable, customerType);
                customerService.saveInfo(customerOperationBean);
                return;
            }
            //证件号存在 ，客户一级表存在 时 验证路由信息
            this.checkCacheMapping(req.getTenantId(), req.getUserId(), req.getChannel(), req.getMobile(), cacheMapping.getCustomerId());

            //根据证件号和渠道，tenanId查询分路由
            CacheMapping cacheMappingChannel = cacheMappingService.selectCacheByIdNumberAndChannel(req.getTenantId(), req.getIdNumber(), req.getChannel(),true);
            if (null == cacheMappingChannel) {
                this.checkSecond(firstlevel.getCustomerId(),req.getUserId(), req.getChannel(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerOperationBean(req, firstlevel, null, channelTable, customerType);
                customerService.saveInfo(customerOperationBean);
                return;
            }

            CmCustomerSecondLevel secondLevel = customerService.getSecondByChannelAndCustomerIdAndTensnId(req.getChannel(), firstlevel.getCustomerId(),firstlevel.getTenantId(), null);
            if (null == secondLevel) {
                this.checkSecond(firstlevel.getCustomerId(),req.getUserId(), req.getChannel(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerOperationBean(req, firstlevel, null, channelTable, customerType);
                customerService.saveInfo(customerOperationBean);
                return;
            }

            //二级表存在时 校验二级表
            this.checkSecond(secondLevel, req.getIdNumber(), req.getUserId(), req.getChannel(), req.getMobile());

            CustomerInfoCreationBean customerOperationBean = this.getCustomerOperationBean(req, firstlevel, secondLevel, channelTable, customerType);
            customerService.saveInfo(customerOperationBean);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 客户注册
     *
     * @param req 客户注册请求
     */
    @Override
    public void customerRegister(CustomerRegisterReq req) throws Exception {
        String lockKey = String.format(CustomerConstant.LOCK_CUST, req.getTenantId(), req.getUserId(),
                req.getChannel());
        logger.info("RedissionLock key:{}", lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.REDIS_LOCK_WAITE_TIME,
                    CustomerConstant.REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}", lockKey, lockFlag);
            if (!lockFlag) {
                logger.error(ErrorMsgConstant.LOCK_EXIST);
                throw new TxnBizException(TxnRespCode.TRANSACTION_PROCESSING.getCode(), TxnRespCode.TRANSACTION_PROCESSING.getMsg());
            }
            //验证证件 起始日期大于终止日期
            this.verifyIdNumberDate(req.getIdEffectiveDate(), req.getIdExpireDate());
            //请求报文校验
            PrChannelTable channelTable = channelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, req.getChannel(), req.getTenantId());
            String privateChannel = channelTable.getPrivateChannel();
            String customerType;
            if (StringUtils.isEmpty(privateChannel) || privateChannel.equals(CustomerConstant.PRIVATE_CHANNEL_YES)) {
                //用注册请求 机构号 客户 客户类型（自营客户）
                customerType = CustomerConstant.CUSTOMER_TYPE_SELF;
            } else {
                //用注册请求 机构号 客户 客户类型（非自营客户）
                customerType = CustomerConstant.CUSTOMER_TYPE_PARTNERSHIP;
            }
            //根据证件号和tenanId查询分路由
            CacheMapping cacheMapping = cacheMappingService.selectFromCacheByIdNumber(req.getTenantId(), req.getIdNumber(), true);
            logger.info("根据证件号[{}]租户[{}]获取路由信息[{}]", req.getIdNumber(), req.getTenantId(), cacheMapping);
            if (null == cacheMapping) {
                this.check(req.getUserId(), req.getChannel(), req.getMobile(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerRegisterBean(req, null, null, channelTable.getOrganizationId(), customerType);
                customerService.registerInfo(customerOperationBean);
                return;
            }
            //路由中存在缓存
            //根据机构+证件类型+证件号查询客户一级信息记录
            CmCustomerFirstLevel firstlevel = customerService.getFirstLevelByCondition(cacheMapping.getCustomerId(), channelTable.getOrganizationId(), req.getTenantId(), req.getIdType(), req.getIdNumber());
            logger.info("根据客户id[{}]证件号[{}租户[{}]机构号[{}]获取客户一级表信息[{}]", cacheMapping.getCustomerId(), req.getIdNumber(), req.getTenantId(), channelTable.getOrganizationId(), firstlevel);

            if (null == firstlevel) {
                this.check(req.getUserId(), req.getChannel(), req.getMobile(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerRegisterBean(req, null, null, channelTable.getOrganizationId(), customerType);
                customerService.registerInfo(customerOperationBean);
                return;
            }

            //证件号存在 ，客户一级表存在 时 验证路由信息
            this.checkCacheMapping(req.getTenantId(), req.getUserId(), req.getChannel(), req.getMobile(), cacheMapping.getCustomerId());

            //根据证件号和渠道，tenanId查询分路由
            CacheMapping cacheMappingChannel = cacheMappingService.selectCacheByIdNumberAndChannel(req.getTenantId(), req.getIdNumber(), req.getChannel(),true);
            if (null == cacheMappingChannel) {
                this.checkSecond(firstlevel.getCustomerId(),req.getUserId(), req.getChannel(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerRegisterBean(req, firstlevel, null, channelTable.getOrganizationId(), customerType);
                customerService.registerInfo(customerOperationBean);
                return;
            }

            CmCustomerSecondLevel secondLevel = customerService.getSecondByChannelAndCustomerIdAndTensnId(req.getChannel(), firstlevel.getCustomerId(),firstlevel.getTenantId(), null);
            if (null == secondLevel) {
                this.checkSecond(firstlevel.getCustomerId(),req.getUserId(), req.getChannel(), req.getTenantId());
                CustomerInfoCreationBean customerOperationBean = this.getCustomerRegisterBean(req, firstlevel, null, channelTable.getOrganizationId(), customerType);
                customerService.registerInfo(customerOperationBean);
                return;
            }

            //二级表存在时 校验二级表
            this.checkSecond(secondLevel, req.getIdNumber(), req.getUserId(), req.getChannel(), req.getMobile());

            CustomerInfoCreationBean customerOperationBean = this.getCustomerRegisterBean(req, firstlevel, secondLevel, channelTable.getOrganizationId(), customerType);
            customerService.registerInfo(customerOperationBean);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 渠道路由不存在或路由存在二级表不存在信息时，校验二级表
     *
     * @param userId   用户id
     * @param channel  渠道
     * @param tenantId 租户id
     * @throws TxnBizException
     */
    private void checkSecond(String customerId,String userId, String channel,String tenantId) throws TxnBizException {
        List<CmCustomerSecondLevel> secondLevelList = customerService.getSecondByCustomerIdAndTensnId( customerId, tenantId);
        if(CollectionUtils.isEmpty(secondLevelList)){
            return;
        }
        for(CmCustomerSecondLevel second : secondLevelList){
            if(second.getUserId().equals(userId) && !second.getChannel().equals(channel)){
                logger.info("该user_id{}在渠道{}已存在", userId, second.getChannel());
                String userIdExist = String.format(ErrorMsgConstant.CUSTOMER_USERID_CHANNEL, userId, second.getChannel());
                throw new TxnBizException(userIdExist);
            }
        }
    }

    /**
     * 二级表存在时 校验二级表
     * @param secondLevel
     * @param idNumber
     * @param userId
     * @param channel
     * @param mobile
     * @throws TxnBizException
     */
    private void checkSecond(CmCustomerSecondLevel secondLevel,String idNumber, String userId, String channel, String mobile) throws TxnBizException {
        if (secondLevel.getChannel().equals(channel)) {
            if (!secondLevel.getUserId().equalsIgnoreCase(userId)) {
                logger.info("该证件号[{}]在该渠道[{}]的请求user_id[{}]与数据库user_id[{}]不统一", idNumber, channel, userId, secondLevel.getUserId());
                String cacheUserId = String.format(ErrorMsgConstant.CUSTOMER_IDNUMBER_CHANNEL, idNumber, channel);
                throw new TxnBizException(cacheUserId);
            }
            if (!secondLevel.getMobile().equalsIgnoreCase(mobile)) {
                logger.info("该证件号[{}]在该渠道[{}]的请求mobile[{}]与数据库mobile[{}]不统一", idNumber, channel, mobile, secondLevel.getMobile());
                String cacheUserId = String.format(ErrorMsgConstant.CUSTOMER_IDNUMBER_CHANNEL, idNumber, channel);
                throw new TxnBizException(cacheUserId);
            }
        }
    }

    /**
     * 客户信息补充
     *
     * @param req 客户信息补充请求
     */
    @Override
    public void customerSupply(CustomerSupplyReq req) throws Exception {

        CustomerInfoCreationBean customerOperationBean = new CustomerInfoCreationBean();
        customerOperationBean.setCustomerSupplyReq(req);

        PrChannelTable channelTable = channelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, req.getChannel(), req.getTenantId());
        //根据租户id ，渠道，手机号查询路由 是否存在 获取客户id
        CacheMapping cacheMapping = cacheMappingService.selectByMobileAndChannel(req.getTenantId(), req.getMobile(), req.getChannel());
        //路由不存在抛异常
        if (cacheMapping == null) {
            String phoneError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_CHANNEL_NO, req.getMobile(), req.getChannel());
            logger.error(phoneError);
            throw new TxnBizException(phoneError);
        }
        //存在 判断证件号 是否 一致
        if (!req.getIdNumber().equalsIgnoreCase(cacheMapping.getIdNumber())) {
            String idNumberError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_IDNUMBER_ERROR, req.getChannel(), req.getMobile(), cacheMapping.getIdNumber(), req.getIdNumber());
            logger.error(idNumberError);
            throw new TxnBizException(ErrorMsgConstant.CARD_MODIFY_ERROR);
        }
        if (!req.getUserId().equalsIgnoreCase(cacheMapping.getUserId())) {
            String userIdError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_USERID_LOG_ERROR, req.getChannel(), req.getMobile(), cacheMapping.getUserId(), req.getUserId());
            logger.error(userIdError);
            throw new TxnBizException(ErrorMsgConstant.CUSTOMER_MOBILE_USERID_ERROR);
        }
        //根据customerid+机构+租户id+证件号 查询客户一级信息记录
        CmCustomerFirstLevel firstlevel = customerService.getFirstLevelByCondition(cacheMapping.getCustomerId(), channelTable.getOrganizationId(), req.getTenantId(), null, req.getIdNumber());
        logger.info("根据客户id[{}]证件号[{}租户[{}]机构号[{}]获取客户一级表信息[{}]", cacheMapping.getCustomerId(), req.getIdNumber(), req.getTenantId(), channelTable.getOrganizationId(), firstlevel);

        if (firstlevel == null) {
            String dataError = String.format(ErrorMsgConstant.CUSTOMER_IDNUMBER_NO_USERID_DATA, req.getIdNumber(), req.getTenantId(), cacheMapping.getCustomerId(), channelTable.getOrganizationId());
            logger.error(dataError);
            throw new TxnBizException(ErrorMsgConstant.CUSTOMER_IDNUMBER_NO_USERID);
        }
        //根据 userId ，租户id，手机号 ，渠道查询客户二级表
        CmCustomerSecondLevel secondLevel = customerService.getSecondLevelByCondition(req.getUserId(), channelTable.getChannelId(), req.getTenantId(), null);
        if (StringUtils.isNotBlank(req.getNationality()) || StringUtils.isNotBlank(req.getRace())) {
            //当国家 或民族不为空的时候修改客户一级表
            customerOperationBean.setModifyCmCustomerFirstLevel(this.buildSupplyFirst(firstlevel, req));
        }
        customerOperationBean.setModifyCmCustomerSecondLevel(this.buildSupplySecond(secondLevel, req));
        //创建地址信息
        List<CmCustomerAddressInfo> address = this.buildeCustomerAddressr(req.getAddressInfoList(), firstlevel.getCustomerId(), channelTable.getOrganizationId(), req.getChannel(), req.getTenantId(), req.getUserId());
        //将集合放入bean中
        customerOperationBean.setAddCmCustomerAddressList(address);
        //创建客户联系人信息
        List<CmCustomerContactInfo> contact = this.builderCustomerContanct(req.getContactInfoList(), firstlevel.getCustomerId(), channelTable.getOrganizationId(), req.getChannel(), req.getTenantId(), req.getUserId());
        //将联系人放入
        customerOperationBean.setAddCmCustomerContactList(contact);
        customerOperationBean.setCustomerId(cacheMapping.getCustomerId());
        customerOperationBean.setTenantId(req.getTenantId());
        customerOperationBean.setOrgId(channelTable.getOrganizationId());
        customerOperationBean.setChannel(req.getChannel());
        customerOperationBean.setEcifUpdate(channelTable.getEcifUpdate());
        customerOperationBean.setEcifCmCustomerFirstLevel(firstlevel);
        customerOperationBean.setEcifCmCustomerSecondLevel(secondLevel);
        customerService.saveInfo(customerOperationBean);
    }


    /**
     * 获取客户注册的保存对象
     *
     * @param req          客户注册
     * @param firstlevel   客户一级表信息
     * @param orgId        机构号
     * @param customerType 客户类型
     * @return CustomerInfoCreationBean
     */
    private CustomerInfoCreationBean getCustomerRegisterBean(CustomerRegisterReq req, CmCustomerFirstLevel firstlevel, CmCustomerSecondLevel secondLevel, String orgId, String customerType) throws SegmentException {
        CustomerInfoCreationBean customerInfoCreationBean = new CustomerInfoCreationBean();
        String customerId;
        //判断库中是否存在客户一级表
        if (null != firstlevel) {
            //如果一级表存在获取customerId
            customerId = firstlevel.getCustomerId();
            //一级表存在，添加到修改对象中
            customerInfoCreationBean.setModifyCmCustomerFirstLevel(this.buildRegisterModifyFirst(firstlevel, req));
            customerInfoCreationBean.setOrgId(firstlevel.getOrganizationId());
            customerInfoCreationBean.setChannel(req.getChannel());
        } else {
            //如果一级表不存在 创建新的customerId
            customerId = String.valueOf(iSegmentService.getId(Constant.CUSTOMER_ID));
            firstlevel = this.buildRegisterAddFirst(req, customerId, orgId);
            //获取主键放入 对象
            firstlevel.setId(iSegmentService.getId(Constant.CM_CUSTOMER_FIRST_LEVEL));
            //不存在 创建客户客户一级表 并放入添加对象
            customerInfoCreationBean.setAddCmCustomerFirstLevel(firstlevel);
            List<TlCustomerLabelLog> labelLogList = tlCustomerLabelLogService.fetchLableLog(firstlevel.getTenantId(),null,null,firstlevel.getIdNumber());
            List<CmCustomerLabel> customerLabelList = customerLabelService.buildCustomerLabel(labelLogList,firstlevel.getCustomerId());
            customerInfoCreationBean.addCustomerLabelList(customerLabelList);
        }
        if (secondLevel != null) {
            customerInfoCreationBean.setModifyCmCustomerSecondLevel(this.buildModifyCustomerSecondLevel(secondLevel, req));
            customerInfoCreationBean.setOrgId(secondLevel.getOrganizationId());
            customerInfoCreationBean.setChannel(req.getChannel());
        } else {
            //二级表不存在 创建添加对象 并放入bean中
            CmCustomerSecondLevel addSecondLevel = this.buildRegisterCustomerSecondLevel(req, customerId, orgId, customerType);
            //获取主键放入 对象
            addSecondLevel.setId(iSegmentService.getId(Constant.CM_CUSTOMER_SECOND_LEVEL));
            customerInfoCreationBean.setAddCmCustomerSecondLevel(addSecondLevel);
            //创建添加路由
            customerInfoCreationBean.setCacheMapping(this.buildCacheMapping(addSecondLevel, req.getIdNumber()));
            customerInfoCreationBean.setCustomerId(customerId);
            customerInfoCreationBean.setTenantId(req.getTenantId());
            customerInfoCreationBean.setOrgId(orgId);
            customerInfoCreationBean.setChannel(req.getChannel());
            List<TlCustomerLabelLog> labelLogList = tlCustomerLabelLogService.fetchLableLog(addSecondLevel.getTenantId(),addSecondLevel.getChannel(),addSecondLevel.getMobile(),null);
            List<CmCustomerLabel> customerLabelList = customerLabelService.buildCustomerLabel(labelLogList,firstlevel.getCustomerId());
            customerInfoCreationBean.addCustomerLabelList(customerLabelList);
        }
        return customerInfoCreationBean;
    }

    /**
     * 客户二级表存在添加
     *
     * @param secondLevel
     * @param req
     * @return
     */
    private CmCustomerSecondLevel buildModifyCustomerSecondLevel(CmCustomerSecondLevel secondLevel, CustomerRegisterReq req) {
        boolean canUpdate = false;
        CmCustomerSecondLevel updateSecond = new CmCustomerSecondLevel();
        if (StringUtils.isNotBlank(req.getMobile()) && !req.getMobile().equals(secondLevel.getMobile())) {
            updateSecond.setMobile(req.getMobile());
            canUpdate = true;
        }
        if (!canUpdate) {
            return null;
        }
        updateSecond.setId(secondLevel.getId());
        updateSecond.setCustomerId(secondLevel.getCustomerId());
        updateSecond.setTenantId(secondLevel.getTenantId());
        updateSecond.setUpdateBy(req.getUserId());
        return updateSecond;
    }

    /**
     * 获取修改的客户一级表信息
     *
     * @param firstlevel 客户一级表
     * @param req        客户补充信息请求
     * @return CmCustomerFirstLevel 修改客户一级表
     */
    private CmCustomerFirstLevel buildSupplyFirst(CmCustomerFirstLevel firstlevel, CustomerSupplyReq req) {
        CmCustomerFirstLevel updateFirst = new CmCustomerFirstLevel();
        boolean canUpdate = false;
        //国家
        if (StringUtils.isNotBlank(req.getNationality()) && !req.getNationality().equals(firstlevel.getNationality())) {
            updateFirst.setNationality(req.getNationality());
            firstlevel.setNationality(req.getNationality());
            canUpdate = true;
        }
        //民族
        if (StringUtils.isNotBlank(req.getRace()) && !req.getRace().equals(firstlevel.getRace())) {
            updateFirst.setRace(req.getRace());
            firstlevel.setRace(req.getRace());
            canUpdate = true;
        }

        if (!canUpdate) {
            return null;
        }
        //主键
        updateFirst.setId(firstlevel.getId());
        //客户id
        updateFirst.setCustomerId(firstlevel.getCustomerId());
        //租户id
        updateFirst.setTenantId(firstlevel.getTenantId());
        //修改人
        updateFirst.setUpdateBy(req.getUserId());
        return updateFirst;
    }


    /**
     * 证件号存在 ，客户一级表存在 时 验证路由信息
     *
     * @param tenantId   租户id
     * @param userId     用户id
     * @param channel    渠道
     * @param mobile     手机号
     * @param customerId 客户id
     * @throws TxnBizException
     */
    private void checkCacheMapping(String tenantId, String userId, String channel, String mobile, String customerId) throws TxnBizException {
        //根据渠道id、用户user_id，查询分库路由
        CacheMapping cacheMapping = cacheMappingService.selectByUserIdAndChannel(tenantId, userId, channel);
        logger.info("客户一级表存在时根据userId:{},渠道:{},租户:{}获取路由信息:{}", userId, channel, tenantId, cacheMapping);
        //路由中存在customerId 且路由中customerId与一级档customerId不一致
        if (null != cacheMapping) {
            if(!cacheMapping.getCustomerId().equalsIgnoreCase(customerId)) {
                String cacheUserId = String.format(ErrorMsgConstant.CUSTOMER_USERID_CHANNEL, userId, channel);
                throw new TxnBizException(cacheUserId);
            }

            if(!cacheMapping.getMobile().equalsIgnoreCase(mobile)) {
                String cacheUserId = String.format(ErrorMsgConstant.CUSTOMER_USERID_CHANNEL, userId, channel);
                throw new TxnBizException(cacheUserId);
            }
        }
        //根据渠道id、手机号，查询分库路由
        cacheMapping = cacheMappingService.selectByMobileAndChannel(tenantId, mobile, channel);
        logger.info("客户一级表存在时根据渠道[{}]手机号[{}]租户[{}]获取客户路由信息[{}]", channel, mobile, tenantId, cacheMapping);
        //路由中存在customerId 且路由中customerId与一级档customerId不一致
        if (null != cacheMapping && !cacheMapping.getCustomerId().equalsIgnoreCase(customerId)) {
            String cacheMobile = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_CHANNEL, mobile, channel);
            throw new TxnBizException(cacheMobile);
        }
    }

    /**
     * 补充客户信息 请求 获取客户二级表的修改对象
     *
     * @param secondLevel 客户二级
     * @param req         补充客户信息请求
     * @return CmCustomerSecondLevel 客户二级表信息
     */
    private CmCustomerSecondLevel buildSupplySecond(CmCustomerSecondLevel secondLevel, CustomerSupplyReq req) {
        CmCustomerSecondLevel updateSecond = new CmCustomerSecondLevel();
        boolean canUpdate = false;
        //公司性质
        if (StringUtils.isNotBlank(req.getCompanyAttribute()) && !req.getCompanyAttribute().equals(secondLevel.getCompanyAttribute())) {
            updateSecond.setCompanyAttribute(req.getCompanyAttribute());
            secondLevel.setCompanyAttribute(req.getCompanyAttribute());
            canUpdate = true;
        }
        //公司名称
        if (StringUtils.isNotBlank(req.getCompanyName()) && !req.getCompanyName().equals(secondLevel.getCompanyName())) {
            updateSecond.setCompanyName(req.getCompanyName());
            secondLevel.setCompanyName(req.getCompanyName());
            canUpdate = true;
        }
        //手机号
        if (StringUtils.isNotBlank(req.getMobile()) && !req.getMobile().equals(secondLevel.getMobile())) {
            updateSecond.setMobile(req.getMobile());
            secondLevel.setCompanyName(req.getMobile());
            canUpdate = true;
        }
        //家庭电话
        if (StringUtils.isNotBlank(req.getHomePhone()) && !req.getHomePhone().equals(secondLevel.getHomePhone())) {
            updateSecond.setHomePhone(req.getHomePhone());
            secondLevel.setHomePhone(req.getHomePhone());
            canUpdate = true;
        }
        //公司电话
        if (StringUtils.isNotBlank(req.getCompanyPhone()) && !req.getCompanyPhone().equals(secondLevel.getCompanyPhone())) {
            updateSecond.setCompanyPhone(req.getCompanyPhone());
            secondLevel.setCompanyPhone(req.getCompanyPhone());
            canUpdate = true;
        }
        //婚姻状态
        if (StringUtils.isNotBlank(req.getMaritalStatus()) && !req.getMaritalStatus().equals(secondLevel.getMaritalStatus())) {
            updateSecond.setMaritalStatus(req.getMaritalStatus());
            secondLevel.setMaritalStatus(req.getMaritalStatus());
            canUpdate = true;
        }
        //教育
        if (StringUtils.isNotBlank(req.getEducation()) && !req.getEducation().equals(secondLevel.getEducation())) {
            updateSecond.setEducation(req.getEducation());
            secondLevel.setEducation(req.getEducation());
            canUpdate = true;
        }
        //职业类型
        if (StringUtils.isNotBlank(req.getOccuptionType()) && !req.getOccuptionType().equals(secondLevel.getOccuptionType())) {
            updateSecond.setOccuptionType(req.getOccuptionType());
            secondLevel.setOccuptionType(req.getOccuptionType());
            canUpdate = true;
        }
        // 居住状况
        if (StringUtils.isNotBlank(req.getFamilyStatus()) && !req.getFamilyStatus().equals(secondLevel.getFamilyStatus())) {
            updateSecond.setFamilyStatus(req.getFamilyStatus());
            secondLevel.setFamilyStatus(req.getFamilyStatus());
            canUpdate = true;
        }
        // 职务
        if (StringUtils.isNotBlank(req.getPosition()) && !req.getPosition().equals(secondLevel.getPosition())) {
            updateSecond.setPosition(req.getPosition());
            secondLevel.setPosition(req.getPosition());
            canUpdate = true;
        }
        // 单位所属行业
        if (StringUtils.isNotBlank(req.getIndustry()) && !req.getIndustry().equals(secondLevel.getIndustry())) {
            updateSecond.setIndustry(req.getIndustry());
            secondLevel.setIndustry(req.getIndustry());
            canUpdate = true;
        }

        // 职业大类
        if (StringUtils.isNotBlank(req.getOccuptionPrimaryType()) && !req.getOccuptionPrimaryType().equals(secondLevel.getOccuptionPriType())) {
            updateSecond.setOccuptionPriType(req.getOccuptionPrimaryType());
            secondLevel.setOccuptionPriType(req.getOccuptionPrimaryType());
            canUpdate = true;
        }

        // 所属行机构编号
        if (StringUtils.isNotBlank(req.getBankOrgNo())) {
            updateSecond.setBankOrgNo(req.getBankOrgNo());
            secondLevel.setBankOrgNo(req.getBankOrgNo());
            canUpdate = true;
        }

        // 客户经理编号
        if (StringUtils.isNotBlank(req.getManagerCode())) {
            updateSecond.setBankMgrNo(req.getManagerCode());
            secondLevel.setBankMgrNo(req.getManagerCode());
            canUpdate = true;
        }

        if (!canUpdate) {
            return null;
        }
        //主键
        updateSecond.setId(secondLevel.getId());
        //客户id
        updateSecond.setCustomerId(secondLevel.getCustomerId());
        //租户id
        updateSecond.setTenantId(secondLevel.getTenantId());
        //修改人
        updateSecond.setUpdateBy(req.getUserId());
        if (StringUtils.isNotBlank(updateSecond.getCustomerGroup())) {
            //客群标识
            updateSecond.setCustomerGroup(req.getCustomerGroup());
        }

        return updateSecond;
    }

    /**
     * 创建客户二级表
     *
     * @param req          客户注册请求
     * @param customerId   客户id
     * @param orgId        机构号
     * @param customerType 客户类型
     * @return 二级表信息
     */
    private CmCustomerSecondLevel buildRegisterCustomerSecondLevel(CustomerRegisterReq req, String customerId, String orgId, String customerType) {
        CmCustomerSecondLevel secondLevel = BeanMapping.copy(req, CmCustomerSecondLevel.class);
        secondLevel.setCustomerId(customerId);
        secondLevel.setOrganizationId(orgId);
        secondLevel.setCustomerStatus(CustomerConstant.STATUS_NORMAL);
        secondLevel.setCustomerType(customerType);
        secondLevel.setUpdateBy(req.getUserId());
        secondLevel.setRecordVersionNumber(Constant.VERSION_NUMBER);
        secondLevel.setRecommenderCode(req.getRecommenderCode());
        if(StringUtils.isNotBlank(req.getUnionId())){
            secondLevel.setUnionId(req.getUnionId());
        }
        return secondLevel;
    }

    /**
     * 客户一级表 修改信息
     *
     * @param firstlevel 一级表
     * @param req        注册请求
     * @return 修改属性
     */
    private CmCustomerFirstLevel buildRegisterModifyFirst(CmCustomerFirstLevel firstlevel, CustomerRegisterReq req) {
        boolean canUpdate = false;
        CmCustomerFirstLevel updateFirst = new CmCustomerFirstLevel();
        if (StringUtils.isNotBlank(req.getIdIssueAgent()) && !req.getIdIssueAgent().equals(firstlevel.getIdIssueAgent())) {
            updateFirst.setIdIssueAgent(req.getIdIssueAgent());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getIdEffectiveDate()) && !req.getIdEffectiveDate().equals(firstlevel.getIdEffectiveDate())) {
            updateFirst.setIdEffectiveDate(req.getIdEffectiveDate());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getIdExpireDate()) && !req.getIdExpireDate().equals(firstlevel.getIdExpireDate())) {
            updateFirst.setIdExpireDate(req.getIdExpireDate());
            canUpdate = true;
        }

        if (!canUpdate) {
            return null;
        }

        updateFirst.setId(firstlevel.getId());
        updateFirst.setCustomerId(firstlevel.getCustomerId());
        updateFirst.setTenantId(firstlevel.getTenantId());
        updateFirst.setUpdateBy(req.getUserId());
        return updateFirst;
    }

    /**
     * 客户注册的 创建添加客户一级表
     *
     * @param req        请求
     * @param customerId 客户id
     * @param orgId      机构号
     * @return 客户一级表
     */
    private CmCustomerFirstLevel buildRegisterAddFirst(CustomerRegisterReq req, String customerId, String orgId) {
        //将客户注册请求赋值到客户一级表
        CmCustomerFirstLevel firstLevel = BeanMapping.copy(req, CmCustomerFirstLevel.class);
        //客户id
        firstLevel.setCustomerId(customerId);
        //机构号
        firstLevel.setOrganizationId(orgId);
        //客户状态
        firstLevel.setCustomerStatus(CustomerConstant.STATUS_NORMAL);
        //生日
        firstLevel.setBirthDate(DateUtils.parseDate(req.getBirthDate()));
        //用户id
        firstLevel.setUpdateBy(req.getUserId());
        firstLevel.setRecordVersionNumber(Constant.VERSION_NUMBER);
        return firstLevel;
    }

    /**
     * 证件号的路由不存在或路由存在一级表不存在信息时，校验路由信息
     *
     * @param userId   用户id
     * @param channel  渠道
     * @param mobile   手机号
     * @param tenantId 租户id
     * @throws TxnBizException
     */
    private void check(String userId, String channel, String mobile, String tenantId) throws TxnBizException {
        //根据渠道id、用户user_id，查询分库路由
        CacheMapping cacheUserIdMapping = cacheMappingService.selectByUserIdAndChannel(tenantId, userId, channel);
        logger.info("客户一级表不存在时根据userId[{}]渠道[{}]租户[{}]获取路由信息[{}]", userId, channel, tenantId, cacheUserIdMapping);
        if (null != cacheUserIdMapping) {
            String userIdExist = String.format(ErrorMsgConstant.CUSTOMER_USERID_CHANNEL, userId, channel);
            throw new TxnBizException(userIdExist);
        }
        //根据渠道id、手机号，查询分库路由
        CacheMapping cacheMobileMapping = cacheMappingService.selectByMobileAndChannel(tenantId, mobile,channel );
        logger.info("客户一级表不存在时根据渠道[{}]手机号[{}]租户[{}]获取客户路由信息[{}]", channel, mobile, tenantId, cacheMobileMapping);
        if (null != cacheMobileMapping) {
            String cacheMobiles = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_CHANNEL, mobile, channel);
            throw new TxnBizException(cacheMobiles);
        }
    }

    /**
     * 客户建档 获取客户保存对象
     *
     * @param req            建档请求
     * @param firstlevel     一级表
     * @param secondLevel    二级表
     * @param prChannelTable 渠道信息
     * @param customerType   客户类型
     */
    private CustomerInfoCreationBean getCustomerOperationBean(CustomerReq req, CmCustomerFirstLevel firstlevel, CmCustomerSecondLevel secondLevel, PrChannelTable prChannelTable, String customerType) throws SegmentException {
        CustomerInfoCreationBean customerInfoCreationBean = new CustomerInfoCreationBean();
        String orgId = prChannelTable.getOrganizationId();
        String customerId;
        //判断库中是否存在客户一级表
        if (null != firstlevel) {
            //如果一级表存在获取customerId
            customerId = firstlevel.getCustomerId();
            //一级表存在，添加到修改对象中
            CmCustomerFirstLevel updateFirst = this.buildCreationModifyFirst(firstlevel, req);
            customerInfoCreationBean.setModifyCmCustomerFirstLevel(updateFirst);
            customerInfoCreationBean.setEcifCmCustomerFirstLevel(firstlevel);
        } else {
            //如果一级表不存在 创建新的customerId
            customerId = String.valueOf(iSegmentService.getId(Constant.CUSTOMER_ID));
            firstlevel = this.buildCreationAddFirst(req, customerId, orgId);
            //获取主键放入 对象
            firstlevel.setId(iSegmentService.getId(Constant.CM_CUSTOMER_FIRST_LEVEL));
            //不存在 创建客户客户一级表 并放入添加对象
            customerInfoCreationBean.setAddCmCustomerFirstLevel(firstlevel);
            customerInfoCreationBean.setEcifCmCustomerFirstLevel(firstlevel);
            List<TlCustomerLabelLog> labelLogList = tlCustomerLabelLogService.fetchLableLog(firstlevel.getTenantId(),null,null,firstlevel.getIdNumber());
            List<CmCustomerLabel> customerLabelList = customerLabelService.buildCustomerLabel(labelLogList,firstlevel.getCustomerId());
            customerInfoCreationBean.addCustomerLabelList(customerLabelList);
        }

        //判断库中是否存在客户二级表数据
        if (null != secondLevel) {
            //二级表存在 放入修改对象
            CmCustomerSecondLevel updateSecond = this.buildCreationModifySecond(secondLevel, req);
            customerInfoCreationBean.setModifyCmCustomerSecondLevel(updateSecond);
            customerInfoCreationBean.setEcifCmCustomerSecondLevel(secondLevel);
        } else {
            //二级表不存在 创建添加对象 并放入bean中
            secondLevel = this.buildCreationAddSecond(req, customerId, orgId, customerType);
            //获取主键放入 对象
            secondLevel.setId(iSegmentService.getId(Constant.CM_CUSTOMER_SECOND_LEVEL));
            customerInfoCreationBean.setAddCmCustomerSecondLevel(secondLevel);
            //创建添加路由
            customerInfoCreationBean.setCacheMapping(this.buildCacheMapping(secondLevel, req.getIdNumber()));
            customerInfoCreationBean.setEcifCmCustomerSecondLevel(secondLevel);
            List<TlCustomerLabelLog> labelLogList = tlCustomerLabelLogService.fetchLableLog(secondLevel.getTenantId(),secondLevel.getChannel(),secondLevel.getMobile(),null);
            List<CmCustomerLabel> customerLabelList = customerLabelService.buildCustomerLabel(labelLogList,firstlevel.getCustomerId());
            customerInfoCreationBean.addCustomerLabelList(customerLabelList);
        }

        //创建地址信息
        List<CmCustomerAddressInfo> address = this.buildeCustomerAddressr(req.getAddressInfoList(), customerId, orgId, req.getChannel(), req.getTenantId(), req.getUserId());
        //将集合放入bean中
        customerInfoCreationBean.setAddCmCustomerAddressList(address);
        //创建客户联系人信息
        List<CmCustomerContactInfo> contact = this.builderCustomerContanct(req.getContactInfoList(), customerId, orgId, req.getChannel(), req.getTenantId(), req.getUserId());
        //将联系人放入
        customerInfoCreationBean.setAddCmCustomerContactList(contact);
        customerInfoCreationBean.setCustomerId(customerId);
        customerInfoCreationBean.setTenantId(req.getTenantId());
        customerInfoCreationBean.setOrgId(orgId);
        customerInfoCreationBean.setChannel(req.getChannel());
        customerInfoCreationBean.setEcifUpdate(prChannelTable.getEcifUpdate());
        return customerInfoCreationBean;
    }

    /**
     * 客户建档 构建更新一级档
     *
     * @param orgiFirst 客户一级表
     * @param req       建档请求
     * @return
     */
    private CmCustomerFirstLevel buildCreationModifyFirst(CmCustomerFirstLevel orgiFirst, CustomerReq req) {
        boolean canUpdate = false;
        CmCustomerFirstLevel updateFirst = new CmCustomerFirstLevel();
        if (StringUtils.isNotBlank(req.getIdIssueAgent()) && !req.getIdIssueAgent().equals(orgiFirst.getIdIssueAgent())) {
            updateFirst.setIdIssueAgent(req.getIdIssueAgent());
            orgiFirst.setIdIssueAgent(req.getIdIssueAgent());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getIdEffectiveDate()) && !req.getIdEffectiveDate().equals(orgiFirst.getIdEffectiveDate())) {
            updateFirst.setIdEffectiveDate(req.getIdEffectiveDate());
            orgiFirst.setIdEffectiveDate(req.getIdEffectiveDate());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getIdExpireDate()) && !req.getIdExpireDate().equals(orgiFirst.getIdExpireDate())) {
            updateFirst.setIdExpireDate(req.getIdExpireDate());
            orgiFirst.setIdExpireDate(req.getIdExpireDate());
            canUpdate = true;
        }

        if (!canUpdate) {
            return null;
        }

        updateFirst.setId(orgiFirst.getId());
        updateFirst.setCustomerId(orgiFirst.getCustomerId());
        updateFirst.setTenantId(orgiFirst.getTenantId());
        updateFirst.setUpdateBy(req.getUserId());
        return updateFirst;
    }

    /**
     * 客户建档 构建更新二级档
     *
     * @param orgiSecond 客户二级表
     * @param req        建档请求
     * @return
     */
    private CmCustomerSecondLevel buildCreationModifySecond(CmCustomerSecondLevel orgiSecond, CustomerReq req) {
        boolean canUpdate = false;
        CmCustomerSecondLevel updateSecond = new CmCustomerSecondLevel();
        if (StringUtils.isNotBlank(req.getMobile()) && !req.getMobile().equals(orgiSecond.getMobile())) {
            updateSecond.setMobile(req.getMobile());
            orgiSecond.setMobile(req.getMobile());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getHomePhone()) && !req.getHomePhone().equals(orgiSecond.getHomePhone())) {
            updateSecond.setHomePhone(req.getHomePhone());
            orgiSecond.setHomePhone(req.getHomePhone());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getCompanyAttribute()) && !req.getCompanyAttribute().equals(orgiSecond.getCompanyAttribute())) {
            updateSecond.setCompanyAttribute(req.getCompanyAttribute());
            orgiSecond.setCompanyAttribute(req.getCompanyAttribute());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getCompanyName()) && !req.getCompanyName().equals(orgiSecond.getCompanyName())) {
            updateSecond.setCompanyName(req.getCompanyName());
            orgiSecond.setCompanyAttribute(req.getCompanyName());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getCompanyPhone()) && !req.getCompanyPhone().equals(orgiSecond.getCompanyPhone())) {
            updateSecond.setCompanyPhone(req.getCompanyPhone());
            orgiSecond.setCompanyName(req.getCompanyPhone());
            canUpdate = true;
        }

        if (StringUtils.isNotBlank(req.getOccuptionType()) && !req.getOccuptionType().equals(orgiSecond.getOccuptionType())) {
            updateSecond.setOccuptionType(req.getOccuptionType());
            orgiSecond.setOccuptionType(req.getOccuptionType());
            canUpdate = true;
        }

        // 居住状况
        if (StringUtils.isNotBlank(req.getFamilyStatus()) && !req.getFamilyStatus().equals(orgiSecond.getFamilyStatus())) {
            updateSecond.setFamilyStatus(req.getFamilyStatus());
            orgiSecond.setFamilyStatus(req.getFamilyStatus());
            canUpdate = true;
        }

        // 职务
        if (StringUtils.isNotBlank(req.getPosition()) && !req.getPosition().equals(orgiSecond.getPosition())) {
            updateSecond.setPosition(req.getPosition());
            orgiSecond.setPosition(req.getPosition());
            canUpdate = true;
        }

        // 单位所属行业
        if (StringUtils.isNotBlank(req.getIndustry()) && !req.getIndustry().equals(orgiSecond.getIndustry())) {
            updateSecond.setIndustry(req.getIndustry());
            orgiSecond.setIndustry(req.getIndustry());
            canUpdate = true;
        }

        if (!canUpdate) {
            return null;
        }

        updateSecond.setId(orgiSecond.getId());
        updateSecond.setCustomerId(orgiSecond.getCustomerId());
        updateSecond.setTenantId(orgiSecond.getTenantId());
        updateSecond.setUpdateBy(req.getUserId());
        return updateSecond;
    }


    /**
     * 创建添加路由信息
     *
     * @param secondLevel 二级表信息
     * @param idNumber    证件号
     */
    private CacheMapping buildCacheMapping(CmCustomerSecondLevel secondLevel, String idNumber) {
        //生命路由
        CacheMapping cacheMapping = new CacheMapping();
        //userId
        cacheMapping.setUserId(secondLevel.getUserId());
        //渠道
        cacheMapping.setChannel(secondLevel.getChannel());
        //客户id
        cacheMapping.setCustomerId(secondLevel.getCustomerId());
        //证件号
        cacheMapping.setIdNumber(idNumber);
        //机构号
        cacheMapping.setMobile(secondLevel.getMobile());
        //租户id
        cacheMapping.setTenantId(secondLevel.getTenantId());
        return cacheMapping;
    }

    /**
     * 客户建档 构造 添加一级表信息
     *
     * @param req        api 传递过来的参数
     * @param customerId 客户Id
     * @param orgId      机构号
     * @return 一级表信息
     */
    private CmCustomerFirstLevel buildCreationAddFirst(CustomerReq req, String customerId, String orgId) {
        CmCustomerFirstLevel firstLevel = BeanMapping.copy(req, CmCustomerFirstLevel.class);
        //客户id
        firstLevel.setCustomerId(customerId);
        //机构号
        firstLevel.setOrganizationId(orgId);
        //状态 默认正常
        firstLevel.setCustomerStatus(CustomerConstant.STATUS_NORMAL);
        //出生日期
        firstLevel.setBirthDate(DateUtils.parseDate(req.getBirthDate()));
        //修改人
        firstLevel.setUpdateBy(req.getUserId());
        //版本号
        firstLevel.setRecordVersionNumber(Constant.VERSION_NUMBER);
        return firstLevel;
    }

    /**
     * 客户建档 构造 添加二级表信息
     *
     * @param req        api 传递过来的参数
     * @param customerId 客户Id
     * @return 二级表信息
     */
    private CmCustomerSecondLevel buildCreationAddSecond(CustomerReq req, String customerId, String orgId, String customerType) {
        //将请求中的值复制到 客户二级表中
        CmCustomerSecondLevel secondLevel = BeanMapping.copy(req, CmCustomerSecondLevel.class);
        //客户id
        secondLevel.setCustomerId(customerId);
        //机构号
        secondLevel.setOrganizationId(orgId);
        //客户状态
        secondLevel.setCustomerStatus(CustomerConstant.STATUS_NORMAL);
        //客户类型
        secondLevel.setCustomerType(customerType);
        //修改人
        secondLevel.setUpdateBy(req.getUserId());
        //版本号
        secondLevel.setRecordVersionNumber(Constant.VERSION_NUMBER);
        //婚姻状态
        secondLevel.setMaritalStatus(req.getMaritalStatus());
        //学历
        secondLevel.setEducation(req.getEducation());
        //职业类型
        secondLevel.setOccuptionType(req.getOccuptionType());
        //推荐人编码
        secondLevel.setRecommenderCode(req.getRecommenderCode());
        //子渠道ID
        secondLevel.setSubChannel(req.getSubChannel());
        return secondLevel;
    }

    /**
     * 生成客户地址信息
     *
     * @param infoes     api传递数据
     * @param customerId 客户Id
     * @param orgId      渠道组织Id
     * @param channel    渠道号
     * @return 客户地址信息
     */
    private List<CmCustomerAddressInfo> buildeCustomerAddressr(List<AddressInfoReq> infoes, String customerId, String orgId, String channel, String tenantId, String userId) throws SegmentException {
        List<CmCustomerAddressInfo> result = new ArrayList<>();
        CmCustomerAddressInfo info;
        if (infoes == null || infoes.isEmpty()) {
            return result;
        }
        for (AddressInfoReq item : infoes) {
            info = BeanMapping.copy(item, CmCustomerAddressInfo.class);
            //客户地址信息主键
            info.setId(iSegmentService.getId(Constant.CM_CUSTOMER_ADDRESS_INFO));
            info.setCustomerId(customerId);
            info.setOrganizationId(orgId);
            info.setTenantId(tenantId);
            info.setAddressStatus(CustomerConstant.STATUS_NORMAL);
            info.setChannel(channel);
            info.setUpdateBy(userId);
            info.setRecordVersionNumber(Constant.VERSION_NUMBER);
            result.add(info);
        }
        return result;
    }

    /**
     * 生成客户联系人信息
     *
     * @param infoes api传递数据
     * @return 客户联系人信息
     */
    private List<CmCustomerContactInfo> builderCustomerContanct(List<ContactInfoReq> infoes, String customerId, String orgId, String channel, String tenantId, String userId) throws SegmentException {
        List<CmCustomerContactInfo> result = new ArrayList<>();
        CmCustomerContactInfo info;
        if (infoes == null || infoes.isEmpty()) {
            return result;
        }
        for (ContactInfoReq item : infoes) {
            info = BeanMapping.copy(item, CmCustomerContactInfo.class);
            //客户联系人信息主键生成
            info.setId(iSegmentService.getId(Constant.CM_CUSTOMER_CONTACT_INFO));
            info.setCustomerId(customerId);
            info.setOrganizationId(orgId);
            info.setChannel(channel);
            info.setTenantId(tenantId);
            info.setContactStatus(CustomerConstant.STATUS_NORMAL);
            if (StringUtils.isNotBlank(item.getIncome())) {
                info.setIncome(Integer.valueOf(item.getIncome()));
            }
            info.setUpdateBy(userId);
            info.setRecordVersionNumber(Constant.VERSION_NUMBER);
            result.add(info);
        }
        return result;
    }

    /**
     * 验证证件 起始日期大于终止日期
     *
     * @param idEffectiveDate 证件有效期起始日期
     * @param idExpireDate    证件有效期终止日期
     */
    private void verifyIdNumberDate(String idEffectiveDate, String idExpireDate) {
        //当终止日期不为长期时
        if (!CustomerConstant.ID_CARD_TYPE.equalsIgnoreCase(idExpireDate)) {
            if (!DateUtils.compare(idEffectiveDate, idExpireDate)) {
                String errMsg = String.format(ErrorMsgConstant.CUSTOMER_ID_EFFECTIVE_ERROR, idEffectiveDate, idExpireDate);
                logger.error(errMsg);
                throw new TxnArgumentException(errMsg);
            }
        }
    }

    @Override
    public void modifyMobile(CustomeMobileModifyReq req) throws Exception {
        String userId = req.getUserId();
        String channel = req.getChannel();
        String tenantId = req.getTenantId();
        String mobile = req.getMobile();
        customerService.customerMobileUpdate(userId, tenantId, channel, mobile);
    }

    /**
     * 保存用户注册时营销数据
     *
     * @param req
     */
    @Override
    public void saveRegMarketingRecord(CustomeRegisterMarketingRecordReq req) throws Exception {
        PrChannelTable channelTable = channelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, req.getChannel(), req.getTenantId());
        //根据渠道信息判断是否需要记录营销记录
        if (CustomerConstant.YES_FLAG.equals(channelTable.getMarketingRecordFlag())) {
            MarketingRecordCreationBean marketingRecordCreationBean = new MarketingRecordCreationBean();
            CmCustomerFirstLevel firstLevel = new CmCustomerFirstLevel();
            CmCustomerSecondLevel secondLevel = new CmCustomerSecondLevel();
            secondLevel.setMobile(req.getMobile());
            secondLevel.setTenantId(req.getTenantId());
            secondLevel.setUserId(req.getUserId());
            secondLevel.setChannel(req.getChannel());
            secondLevel.setCustomerId("0");
            secondLevel.setRecommenderCode(req.getRecommenderCode());
            marketingRecordCreationBean.setCustomerFirstLevel(firstLevel);
            marketingRecordCreationBean.setCustomerSecondLevel(secondLevel);
            marketingRecordCreationBean.setAddressInfoList(new ArrayList<>());
            marketingRecordCreationBean.setCustomerLimitInfoList(new ArrayList<>());
            marketingRecordCreationBean.setStep(CustomerConstant.MARKET_STEP_1);
            marketingRecordCreationBean.setSeqNo(req.getSeqNo());
            TlMarketingRecord result = customerService.generateMarketingRecord(marketingRecordCreationBean);

            if (null != result) {
                result.setId(iSegmentService.getId(Constant.TL_MARKETING_RECORD));
                int marketAdd = extTlMarketingRecordMapper.insertSelective(result);
                if (marketAdd <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.MARKET_ADD_ERROR);
                }
            } else {
                logger.error("生成营销记录失败，流水号为：{}", req.getSeqNo());
                throw new TxnBizException(ErrorMsgConstant.MARKET_ADD_ERROR);
            }

        }
    }

    /**
     * 证件有效期修改
     *
     * @param req
     */
    @Override
    public void updateIdValidity(IdValidityReq req) throws Exception {
        CmCustomerSecondLevel customerSecondLevel = customerService.getSecondLevelByCondition(req.getUserId(),
                req.getChannel(), req.getTenantId(), null);
        CmCustomerFirstLevel customerFirstLevel = customerService.getFirstLevelByCondition(customerSecondLevel.getCustomerId(),
                customerSecondLevel.getOrganizationId(), customerSecondLevel.getTenantId());
        if (!customerFirstLevel.getIdNumber().equals(req.getIdNumber()) || !customerFirstLevel.getIdType().equals(req.getIdType()))
        {
            logger.error("客户证件信息不一致");
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getMsg());
        }
        CmCustomerFirstLevel updateFirstLevel = new CmCustomerFirstLevel();
        updateFirstLevel.setId(customerFirstLevel.getId());
        updateFirstLevel.setCustomerId(customerFirstLevel.getCustomerId());
        updateFirstLevel.setTenantId(customerFirstLevel.getTenantId());
        updateFirstLevel.setIdEffectiveDate(req.getIdEffectiveDate());
        updateFirstLevel.setIdIssueAgent(req.getIdIssueAgent());
        updateFirstLevel.setIdExpireDate(req.getIdExpireDate());
        customerService.customerIdUpdate(updateFirstLevel);
    }

    /**
     * 修改二级客户表部分信息
     *
     * @param req
     */
    @Override
    public void updateSecondLevel(CustSecondLevelModReq req) {
        try {
            CmCustomerSecondLevel ccsl = customerService.getSecondLevelByCondition(req.getUserId(), req.getChannel(), req.getTenantId(), null);
            if (ccsl == null) {
                throw new TxnBizException(TxnRespCode.NO_DATA);
            }

            CmCustomerSecondLevel updateSecond = new CmCustomerSecondLevel();
            BeanUtils.copyProperties(req, updateSecond);
            updateSecond.setId(ccsl.getId());
            updateSecond.setCustomerId(ccsl.getCustomerId());
            updateSecond.setTenantId(ccsl.getTenantId());

            HistoryLog txnHistoryLog = new HistoryLog(updateSecond.getCustomerId(), updateSecond.getTenantId(), ccsl.getOrganizationId(), ccsl.getChannel(), updateSecond.getUserId(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
            HistoryLogHelper.setLocalHistory(txnHistoryLog);

            extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(updateSecond);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void ecifRegister(CustomerEcifReq req)  throws Exception {
        CustomerInfoCreationBean customerOperationBean = new CustomerInfoCreationBean();
        customerOperationBean.setChannel(req.getChannel());

        PrChannelTable channelTable = channelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, req.getChannel(), req.getTenantId());
        //根据租户id ，渠道，手机号查询路由 是否存在 获取客户id
        CacheMapping cacheMapping = cacheMappingService.selectByMobileAndChannel(req.getTenantId(), req.getMobile(), req.getChannel());
        //路由不存在抛异常
        if (cacheMapping == null) {
            String phoneError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_CHANNEL_NO, req.getMobile(), req.getChannel());
            logger.error(phoneError);
            throw new TxnBizException(phoneError);
        }
        //存在 判断证件号 是否 一致
        if (!req.getIdNumber().equalsIgnoreCase(cacheMapping.getIdNumber())) {
            String idNumberError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_IDNUMBER_ERROR, req.getChannel(), req.getMobile(), cacheMapping.getIdNumber(), req.getIdNumber());
            logger.error(idNumberError);
            throw new TxnBizException(ErrorMsgConstant.CARD_MODIFY_ERROR);
        }
        if (!req.getUserId().equalsIgnoreCase(cacheMapping.getUserId())) {
            String userIdError = String.format(ErrorMsgConstant.CUSTOMER_MOBILE_USERID_LOG_ERROR, req.getChannel(), req.getMobile(), cacheMapping.getUserId(), req.getUserId());
            logger.error(userIdError);
            throw new TxnBizException(ErrorMsgConstant.CUSTOMER_MOBILE_USERID_ERROR);
        }
        //根据customerid+机构+租户id+证件号 查询客户一级信息记录
        CmCustomerFirstLevel firstlevel = customerService.getFirstLevelByCondition(cacheMapping.getCustomerId(), channelTable.getOrganizationId(), req.getTenantId(), null, req.getIdNumber());
        logger.info("根据客户id[{}]证件号[{}租户[{}]机构号[{}]获取客户一级表信息[{}]", cacheMapping.getCustomerId(), req.getIdNumber(), req.getTenantId(), channelTable.getOrganizationId(), firstlevel);

        if (firstlevel == null) {
            String dataError = String.format(ErrorMsgConstant.CUSTOMER_IDNUMBER_NO_USERID_DATA, req.getIdNumber(), req.getTenantId(), cacheMapping.getCustomerId(), channelTable.getOrganizationId());
            logger.error(dataError);
            throw new TxnBizException(ErrorMsgConstant.CUSTOMER_IDNUMBER_NO_USERID);
        }
        //根据 userId ，租户id，手机号 ，渠道查询客户二级表
        CmCustomerSecondLevel secondLevel = customerService.getSecondLevelByCondition(req.getUserId(), channelTable.getChannelId(), req.getTenantId(), null);
        CustomerSupplyReq customerSupplyReq = new CustomerSupplyReq();
        //esb接口中, 此项表明职业大类
        customerSupplyReq.setOccuptionPrimaryType(secondLevel.getOccuptionPriType());
        //esb接口中, 此项表明职业小类
        customerSupplyReq.setOccuptionType(secondLevel.getOccuptionType());
        //客户经理编号
        customerSupplyReq.setManagerCode(secondLevel.getBankMgrNo());
        //开户分支行编号
        customerSupplyReq.setBankOrgNo(secondLevel.getBankOrgNo());
        //签发机关编号
        customerSupplyReq.setDisLegalId(req.getDisLegalId());
        customerSupplyReq.setUserId(req.getUserId());
        customerOperationBean.setCustomerSupplyReq(customerSupplyReq);

        //联系地址表信息
        List<CmCustomerAddressInfo> address = extCmCustomerAddressInfoMapper.selectByCustomerIdAndTenantId(firstlevel.getCustomerId(), firstlevel.getTenantId());
        //将集合放入bean中
        customerOperationBean.setAddCmCustomerAddressList(address);

        //联系人信息
        List<CmCustomerContactInfo> contact = extCmCustomerContactInfoMapper.selectByTenantIdAndCustomerId(firstlevel.getTenantId(),firstlevel.getCustomerId());
        //将联系人放入
        customerOperationBean.setAddCmCustomerContactList(contact);
        customerOperationBean.setCustomerId(cacheMapping.getCustomerId());
        customerOperationBean.setTenantId(req.getTenantId());
        customerOperationBean.setOrgId(StringUtils.isNotBlank(channelTable.getOrganizationId()) ? channelTable.getOrganizationId() : secondLevel.getOrganizationId());
        customerOperationBean.setChannel(req.getChannel());
        customerOperationBean.setEcifUpdate(channelTable.getEcifUpdate());
        customerOperationBean.setEcifCmCustomerFirstLevel(firstlevel);
        customerOperationBean.setEcifCmCustomerSecondLevel(secondLevel);
        customerService.saveEcif(customerOperationBean);
    }

}